package com.papper.mng.controller.sys;

import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.papper.common.bean.sys.SysGroup;
import com.papper.common.bean.sys.SysLimit;
import com.papper.common.bean.sys.SysModel;
import com.papper.common.bean.sys.SysResource;
import com.papper.common.bean.sys.SysSystem;
import com.papper.common.bean.sys.SysUser;
import com.papper.common.enums.DataStatusEnum;
import com.papper.common.enums.LimitTypeEnum;
import com.papper.common.exception.ServiceException;
import com.papper.common.service.sys.SysGroupService;
import com.papper.common.service.sys.SysLimitService;
import com.papper.common.service.sys.SysModelService;
import com.papper.common.service.sys.SysResourceService;
import com.papper.common.service.sys.SysSystemService;
import com.papper.common.service.sys.SysUserService;
import com.papper.common.utils.tool.StringTool;
import com.papper.mng.controller.BaseAction;
import com.papper.mng.domain.DwzResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import tk.mybatis.mapper.util.StringUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/sys/group")
public class SysGroupAction extends BaseAction {

    @Autowired
    SysGroupService    sysGroupService;
    @Autowired
    SysResourceService sysResourceService;
    @Autowired
    SysUserService     sysUserService;
    @Autowired
    SysLimitService    sysLimitService;
    @Autowired
    SysSystemService   sysSystemService;
    @Autowired
    SysModelService    sysModelService;

    /**
     * 角色信息
     *
     * @return
     */
    @RequestMapping(value = "")
    public String execute(HttpServletRequest _request, HttpServletResponse _response, Model model, Long systemId) {
        List<SysSystem> systems = sysSystemService.findAll();
        systemId = systemId == null ? 1 : systemId;
        SysSystem sysSystem = sysSystemService.findById(systemId);
        if (sysSystem == null && systems.size() > 0) {
            sysSystem = systems.get(0);
        }
        if (sysSystem != null) {
            model.addAttribute("systems", systems);
            model.addAttribute("systemId", sysSystem.getId());
            model.addAttribute("sysSystem", sysSystem);
            SysUser        sessionUser = getLoginUser();
            List<SysGroup> groups      = sysGroupService.findByUserId(sysSystem.getId().toString(), sessionUser.getId().toString());
            model.addAttribute("groups", groups);
        }
        return render("sys/group/index");
    }

    /**
     * 角色信息_新增
     *
     * @param pid
     * @throws IOException
     */
    @GetMapping(value = "/add")
    public String add_get(Model model, Long pid, Long systemId) {
        model.addAttribute("sysSystem", sysSystemService.findById(systemId));
        model.addAttribute("nick", getNick());
        model.addAttribute("systemId", systemId);
        if (pid == 0) {
            model.addAttribute("pid", pid);
            model.addAttribute("pname", "顶级角色");
        } else {
            SysGroup parent = sysGroupService.findById(pid);
            model.addAttribute("pid", pid);
            model.addAttribute("pname", parent.getGroupName());
        }
        return render("sys/group/add");
    }

    @PostMapping(value = "/add")
    @ResponseBody
    public DwzResponse add_post(HttpServletRequest _request, SysGroup sysGroup) {
        try {
            checkSuperCert(_request);
        } catch (ServiceException e) {
            return new DwzResponse("300", e.getMessage());
        }
        SysUser sessionUser = getLoginUser();
        if (sysGroup == null) {
            return new DwzResponse("300", "参数异常！");
        }
        sysGroup.setUpFamily("");
        sysGroup.setUserId(sessionUser.getId().intValue());
        sysGroup.setUpChild(0);
        // 添加角色信息
        try {
            sysGroup.setDataStatus(DataStatusEnum.OPEN.getCode());
            sysGroup.setCreateTime(new Date());
            sysGroup.setModifyTime(new Date());
            sysGroupService.save(sysGroup);
        } catch (Exception e) {
            e.printStackTrace();
            return new DwzResponse("300", "角色添加失败:" + e.getMessage() + "!!!");
        }
        // 维护组树信息
        sysGroupService.matchFamily(sysGroup);
        return new DwzResponse("200", "商户注册成功!!!");
    }

    /**
     * 角色信息_更新
     *
     * @param _response
     * @param id
     * @throws IOException
     */
    @GetMapping(value = "/edit")
    public String edti_get(HttpServletResponse _response, Model model, Long id) {
        SysGroup entity = sysGroupService.findById(id);
        model.addAttribute("entity", entity);
        model.addAttribute("sysSystem", sysSystemService.findById(entity.getSystemId()));
        model.addAttribute("sysUser", sysUserService.findById(entity.getUserId()));
        if (entity.getUpId() == 0) {
            model.addAttribute("pid", entity.getUpId());
            model.addAttribute("pname", "顶级角色");
        } else {
            SysGroup parent = sysGroupService.findById(entity.getUpId());
            model.addAttribute("pid", entity.getUpId());
            model.addAttribute("pname", parent.getGroupName());
        }
        return render("sys/group/edit");
    }

    @PostMapping(value = "/edit")
    @ResponseBody
    public DwzResponse edit_post(HttpServletRequest _request, SysGroup sysGroup) {
        try {
            checkSuperCert(_request);
        } catch (ServiceException e) {
            return new DwzResponse("300", e.getMessage());
        }
        SysUser sessionUser = getLoginUser();
        if (sysGroup == null || sysGroup.getId() == null) {
            return new DwzResponse("300", "参数异常！");
        }
        SysGroup old = sysGroupService.findById(sysGroup.getId());
        if (sessionUser.getId().intValue() != old.getUserId().intValue()) {
            return new DwzResponse("300", "您没有权限修改该角色信息！");
        }
        sysGroup.setModifyTime(new Date());
        sysGroupService.update(sysGroup);
        return new DwzResponse("200", "角色信息修改成功!!!");
    }

    /**
     * 角色信息_删除
     *
     * @param _response
     * @param id
     * @throws IOException
     */
    @PostMapping(value = "/del")
    @ResponseBody
    public DwzResponse del_post(HttpServletRequest _request, HttpServletResponse _response, Long id) {
        try {
            checkSuperCert(_request);
        } catch (ServiceException e) {
            return new DwzResponse("300", e.getMessage());
        }
        if (id == null || id.intValue() <= 0) {
            return new DwzResponse("300", "参数异常！");
        }
        SysUser  sessionUser = getLoginUser();
        SysGroup old         = sysGroupService.findById(id);
        if (sessionUser.getId().intValue() != old.getUserId().intValue()) {
            return new DwzResponse("300", "您没有权限删除该组！");
        }
        // 该角色用户信息
        List<SysUser> sysUsers = sysUserService.findByGroupId(old.getId());
        if (sysUsers != null && sysUsers.size() > 0) {
            return new DwzResponse("300", "该角色下尚有使用中用户,暂时无法删除！");
        }
        sysGroupService.deleteSysGroupById(id);
        // 获取子角色
        List<SysGroup> groupList = sysGroupService.findFamily(old.getUpFamily());
        if (groupList != null) {
            for (SysGroup sysGroup : groupList) {
                sysGroupService.deleteSysGroupById(sysGroup.getId());
            }
        }
        return new DwzResponse("200", "角色信息删除成功!!!");
    }

    /**
     * 角色信息_权限设置
     *
     * @param _response
     * @param id
     * @throws IOException
     */
    @GetMapping(value = "/limit")
    public String limit_get(HttpServletResponse _response, Model model, Long id) {
        SysGroup sysGroup = sysGroupService.findById(id);
        if (sysGroup == null) {
            return render("sys/group/limit");
        }
        SysSystem sysSystem = sysSystemService.findById(sysGroup.getSystemId());
        if (sysSystem == null) {
            return render("sys/group/limit");
        }
        model.addAttribute("sysGroup", sysGroup);
        model.addAttribute("sysSystem", sysSystem);
        SysUser sysUser = getLoginUser();
        // 获取系统模块一览
        List<SysModel> sysModels = sysModelService.findByLimit(sysSystem.getId(), sysUser);
        model.addAttribute("sysModels", sysModels);
        // 获取系统资源一览
        List<SysResource> resources = sysResourceService.findLimitBySystemId(sysSystem.getId(), sysUser);
        // 获取权限一览
        List<SysLimit>        limits   = sysLimitService.getUserLimits(LimitTypeEnum.GROUP.getCode(), sysGroup.getId());
        Map<Integer, Integer> oldLimit = Maps.newHashMap();
        if (limits != null) {
            for (SysLimit sysLimit : limits) {
                oldLimit.put(sysLimit.getResId(), sysLimit.getLimitValue());
            }
        }
        // 组装数据
        List<SysResource>            temp          = null;
        Map<Long, List<SysResource>> modelResource = Maps.newLinkedHashMap();
        for (SysResource sysResource : resources) {
            if (oldLimit.get(sysResource.getId().intValue()) != null) {
                sysResource.setLimitValue(oldLimit.get(sysResource.getId().intValue()));
            }
            temp = modelResource.get(sysResource.getModelId().longValue());
            if (temp == null) {
                temp = Lists.newArrayList();
            }
            temp.add(sysResource);
            modelResource.put(sysResource.getModelId().longValue(), temp);
        }
        for (Long rid : modelResource.keySet()) {
            modelResource.put(rid, sysResourceService.treeChildList(modelResource.get(rid)));
        }
        model.addAttribute("modelResource", modelResource);
        return render("sys/group/limit");
    }

    @PostMapping(value = "/limit")
    @ResponseBody
    public DwzResponse limit_post(HttpServletRequest _request, String gid, String limits) {
        try {
            checkSuperCert(_request);
        } catch (ServiceException e) {
            return new DwzResponse("300", e.getMessage());
        }
        if (StringUtil.isEmpty(gid)) {
            return new DwzResponse("300", "参数[gid]为空！");
        }
        SysGroup sysGroup = sysGroupService.findById(gid);
        if (sysGroup == null) {
            return new DwzResponse("300", "参数[gid]信息异常！");
        }
        SysUser sessionUser = getLoginUser();
        if (!isSuperUser() && sysGroup.getUserId().intValue() != sessionUser.getId().intValue()) {
            return new DwzResponse("300", "您无权限操作该用户！");
        }
        // 权限设置
        List<SysLimit> modifyLimits = Lists.newArrayList();
        SysLimit       sysLimit;
        List<String>   ids          = Splitter.on(',').trimResults().omitEmptyStrings().splitToList(limits);
        if (ids != null) {
            for (String id : ids) {
                if (StringTool.parseInteger(id, 0) <= 0) {
                    continue;
                }
                sysLimit = new SysLimit();
                sysLimit.setLimitType(LimitTypeEnum.GROUP.getCode());
                sysLimit.setLimitId(StringTool.parseInteger(gid, null));
                sysLimit.setResId(StringTool.parseInteger(id, null));
                sysLimit.setLimitValue(1);
                modifyLimits.add(sysLimit);
            }
        }
        try {
            // 添加新权限信息
            sysLimitService.delLimitedByGroupIds(gid);
            // 清空权限信息
            sysLimitService.batchInsert(modifyLimits);
            return new DwzResponse("200", "权限保存成功!!!");
        } catch (Exception e) {
            e.printStackTrace();
            return new DwzResponse("300", "系统错误,请稍候再试!!![" + e.getMessage() + "]");
        }
    }
}
